浅谈视频翻录 - 0

作者:智多星
日期:2024年3月1日

出于对 知识 的热爱,我对以下样本进行了研究。

上面俩个软件样本都拥有 Windows 、Android 版本。大黄蜂视频加密 似乎由于经费不足而引起的开发动力不足,更新缓慢,难以对抗市面上的翻录手段。深造视频加密 并没有透露过多的更新内容,与 大黄蜂视频加密 相比,它的防破解强度较高。接下来的内容,从介绍 深造视频加密 开始。

深造视频加密

软件介绍:

本地视频、在线视频、直播视频加密系统(整套系统永久、全平台、一机一码)
我们承诺随时翻录破解随时全额退款!
我们承诺,翻录一个视频奖励500元,破解一个视频奖励1000元,10万元封顶,支付宝直接转账!!!

样本版本(Windows):

版本:23.12.513  大小:41.7MB    发布日期:2023年12月29日
(2)、播放器会检测采集卡翻录、软件翻录、破解调试、虚拟机翻录、隐藏进程、AI行为识别翻录、数据分析识别翻录、手机摄像机拍摄翻             录等,请尊重视频著作权!对于恶意破坏者收回权限处理!情节严重,我们会对涉及侵权等违法行为搜集资料并起诉;
(3)、播放过程中不要外接U盘和移动硬盘,不要更换电脑CPU、主板、硬盘、显示器等,否则会导致电脑机器码超限;

样本版本(Android):

大小:104MB   版本:23.12.106  发布日期:2023年12月26日
(1)、深造播放器是一款逐帧加密的混合式视频加密播放器,用于保护视频版权;需要android 9.0以上系统,或者鸿蒙系统;
(2)、安卓手机要关闭开发者模式、关闭USB调试、播放过程中禁止手机连接电脑;
(3)、安卓播放器禁止:虚拟机录屏、软件录屏、投屏录屏、外接采集卡录屏、root环境、模拟器环境;

Android 端分析

由于 Windows 端添加了 Safengine 加密壳保护,我搞不定,不了解 Windows 逆向。所以优先从 Android 端入手逆向。

准备如下环境工具:

通过 mt 管理器深造播放器 进行解析。

来,在这里跟 智多星 积累俩个单词。媒体:media 播放器:player

我们知道,程序加壳了,要想 完美逆向 便需要进行 脱壳。但这是 360加固 ,要想将其脱掉,对于 初学者 来说也许得花点时间去学习下 Android 程序加载原理 了。

在我查看了几篇 安卓逆向文档 后,发现 Android 程序 的运行,一般分为俩层。分别是 java 层,native 层。 java 层的代码是可以进行反编译的,即可以将其还原成源代码查看。

我迫不及待地去学习新的知识,发现 java 层的代码存储于一个后缀名为 .dex 的文件里。我发现一种内存修改工具,名为 game guardian (游戏保护)。可以通过它获取进程内存中的数据。

深造播放器 dex 版本:

dex 035
64 65 78 0A 30 33 35 00

上面的十六进制数据便是 .dex 文件的特征码。game guardian 附加上 目标进程 ,勾选内存范围 jh (java heap),搜索如上十六进制数据 dump 下来便是 360 加固解密后的 .dex 文件啦。

使用 mt 管理器 对 dump 下来的文件进行 dex 编辑++。查看 io.antiengine 相关代码,这是 深造播放器 防破解的源头。

该类含有以下方法:

为什么方法名要用 info 呢?我猜测,是因为其防破解原理主要是通过 获取系统相关信息 来完成的。

io.antiengine.info0:

调用 info1
调用 isSafe
获取 pageName list
获取 传感器数量
获取 显示屏数量
获取 Usb 信息
获取 Adb 信息
获取 su 信息
获取 emulator 信息
获取 virtual circumstance

呵呵,相对于 pdd 等大厂软件获取的系统信息,sz 算是温柔地了。

发现 info1native 层的函数,我通过查阅文档发现其是 .so export method (so 是 Android 系统下的动态链接库)。

_init:

str soName = "eagle_sdk";
loadLibrary(soName);

我们将 data/app/.../lib/ 文件夹下的 eagle_sdk.so 提取出来,拖入 ida 中进行反编译。.so 文件是未加壳的,呵呵,看样子 深造视频加密2021 年开始推行的 深造播放器 Android 并没有多安全。

__int64 __fastcall Java_io_eagle_sdk_AntiEngine_info1(__int64 a1)
{
  int v1; // eax
  const char *v2; // r15
  size_t v3; // rax
  size_t v4; // r13
  char *v5; // r12
  unsigned __int64 v6; // rbx
  __int64 v7; // rax
  char *v8; // rsi
  __int64 v9; // rbx
  void *v10; // rdi
  unsigned __int64 v11; // rax
  __int64 (__fastcall *v12)(__int64, const char *); // rcx
  __int64 v13; // rax
  __int128 dest; // [rsp+0h] [rbp-68h] BYREF
  void *v16; // [rsp+10h] [rbp-58h]
  __int128 v17; // [rsp+20h] [rbp-48h] BYREF
  void *ptr; // [rsp+30h] [rbp-38h]
  unsigned __int64 v19; // [rsp+38h] [rbp-30h]

  v19 = __readfsqword(0x28u);
  v1 = sub_14CA0();                             // root
  if ( v1 || (v1 = sub_151E0()) != 0 )          // magisk and virual circumstance...
  {
    if ( v1 == 1 )
      goto LABEL_4;
  }
  else if ( (unsigned int)sub_157F0() == 1 )    // adb
  {
LABEL_4:
    v2 = (const char *)sub_151D0();
    dest = 0LL;
    v16 = 0LL;
    v3 = strlen(v2);
    if ( v3 >= 0xFFFFFFFFFFFFFFF0LL )
      sub_14C10(&dest);
    v4 = v3;
    if ( v3 >= 0x17 )
    {
      v6 = (v3 + 16) & 0xFFFFFFFFFFFFFFF0LL;
      v5 = (char *)operator new(v6);
      v16 = v5;
      *(_QWORD *)&dest = v6 | 1;
      *((_QWORD *)&dest + 1) = v4;
    }
    else
    {
      LOBYTE(dest) = 2 * v3;
      v5 = (char *)&dest + 1;
      if ( !v3 )
      {
LABEL_10:
        v5[v4] = 0;
        v7 = sub_16AD0(&dest, 0LL, "1:", 2LL);
        ptr = *(void **)(v7 + 16);
        v17 = *(_OWORD *)v7;
        *(_OWORD *)v7 = 0LL;
        *(_QWORD *)(v7 + 16) = 0LL;
        if ( (v17 & 1) != 0 )
          v8 = (char *)ptr;
        else
          v8 = (char *)&v17 + 1;
        v9 = (*(__int64 (__fastcall **)(__int64, char *))(*(_QWORD *)a1 + 1336LL))(a1, v8);
        if ( (v17 & 1) != 0 )
          operator delete(ptr);
        if ( (dest & 1) != 0 )
        {
          v10 = v16;
LABEL_26:
          operator delete(v10);
          return v9;
        }
        return v9;
      }
    }
    memcpy(v5, v2, v4);
    goto LABEL_10;
  }
  sub_16260((__int64)&v17);                     // check emulator and vmos
  if ( (v17 & 1) != 0 )
    v11 = *((_QWORD *)&v17 + 1);
  else
    v11 = (unsigned __int64)(unsigned __int8)v17 >> 1;
  v12 = *(__int64 (__fastcall **)(__int64, const char *))(*(_QWORD *)a1 + 1336LL);
  if ( v11 )
    v13 = v12(a1, "1:Find Simulator");
  else
    v13 = v12(a1, "0:Safe");
  v9 = v13;
  if ( (v17 & 1) != 0 )
  {
    v10 = ptr;
    goto LABEL_26;
  }
  return v9;
}

check su:

// su
__int64 sub_14CA0()
{
  void **v0; // rdi
  const char *v1; // rdi
  bool v2; // al
  const char *v3; // rdi
  bool v4; // al
  const char *v5; // rdi
  bool v6; // al
  const char *v7; // rdi
  bool v8; // al
  const char *v9; // rdi
  bool v10; // al
  const char *v11; // rdi
  bool v12; // al
  const char *v13; // rdi
  bool v14; // al
  unsigned int v15; // ebx
  const char *v16; // rdi
  char v18; // [rsp+0h] [rbp-D8h] BYREF
  char v19[23]; // [rsp+1h] [rbp-D7h] BYREF
  char v20; // [rsp+18h] [rbp-C0h] BYREF
  _BYTE v21[23]; // [rsp+19h] [rbp-BFh] BYREF
  void *v22[3]; // [rsp+30h] [rbp-A8h] BYREF
  char v23; // [rsp+48h] [rbp-90h] BYREF
  _BYTE v24[23]; // [rsp+49h] [rbp-8Fh] BYREF
  void *v25[3]; // [rsp+60h] [rbp-78h] BYREF
  void *v26[3]; // [rsp+78h] [rbp-60h] BYREF
  void *v27[3]; // [rsp+90h] [rbp-48h] BYREF
  __int128 v28; // [rsp+A8h] [rbp-30h] BYREF
  void *v29; // [rsp+B8h] [rbp-20h]
  unsigned __int64 v30; // [rsp+C8h] [rbp-10h]

  v30 = __readfsqword(0x28u);
  *(_QWORD *)&v19[15] = 0LL;
  v18 = 28;
  strcpy(v19, "/system/bin/su");
  v21[16] = 0;
  *(_WORD *)&v21[17] = 0;
  *(_DWORD *)&v21[19] = 0;
  v20 = 30;
  strcpy(v21, "/product/bin/su");
  strcpy((char *)&v22[2] + 1, "su");
  HIDWORD(v22[2]) = 0;
  strcpy((char *)v22, "$/data/local/bin");
  v24[16] = 0;
  *(_WORD *)&v24[17] = 0;
  *(_DWORD *)&v24[19] = 0;
  v23 = 30;
  strcpy(v24, "/system/xbin/su");
  HIBYTE(v25[2]) = 0;
  strcpy((char *)v25, "*/system/xbin/which/su");
  strcpy((char *)&v26[2] + 1, "su");
  HIDWORD(v26[2]) = 0;
  strcpy((char *)v26, "$/data/local/xin");
  strcpy((char *)&v27[2] + 1, "su");
  HIDWORD(v27[2]) = 0;
  strcpy((char *)v27, "$/data/local/bin");
  v29 = (void *)operator new(0x20uLL);
  v28 = xmmword_3B860;
  strcpy((char *)v29, "/system/bin/failsafe/su");
  v0 = (void **)&v18;
  if ( sub_146D0(v19) )
    goto LABEL_30;
  v1 = (v20 & 1) != 0 ? *(const char **)&v21[15] : v21;
  v2 = sub_146D0(v1);
  v0 = (void **)&v20;
  if ( v2 )
    goto LABEL_30;
  v3 = ((__int64)v22[0] & 1) != 0 ? (const char *)v22[2] : (char *)v22 + 1;
  v4 = sub_146D0(v3);
  v0 = v22;
  if ( v4 )
    goto LABEL_30;
  v5 = (v23 & 1) != 0 ? *(const char **)&v24[15] : v24;
  v6 = sub_146D0(v5);
  v0 = (void **)&v23;
  if ( v6 )
    goto LABEL_30;
  v7 = ((__int64)v25[0] & 1) != 0 ? (const char *)v25[2] : (char *)v25 + 1;
  v8 = sub_146D0(v7);
  v0 = v25;
  if ( v8 )
    goto LABEL_30;
  v9 = ((__int64)v26[0] & 1) != 0 ? (const char *)v26[2] : (char *)v26 + 1;
  v10 = sub_146D0(v9);
  v0 = v26;
  if ( v10
    || (((__int64)v27[0] & 1) == 0 ? (v11 = (char *)v27 + 1) : (v11 = (const char *)v27[2]),
        (v12 = sub_146D0(v11), v0 = v27, v12)
     || ((v28 & 1) == 0 ? (v13 = (char *)&v28 + 1) : (v13 = (const char *)v29),
         v14 = sub_146D0(v13),
         v0 = (void **)&v28,
         v15 = 0,
         v14)) )
  {
LABEL_30:
    if ( (*(_BYTE *)v0 & 1) != 0 )
      v16 = (const char *)v0[2];
    else
      v16 = (char *)v0 + 1;
    qword_4C040 = (__int64)strdup(v16);
    v15 = 1;
  }
  if ( (v28 & 1) != 0 )
  {
    operator delete(v29);
    if ( ((__int64)v27[0] & 1) == 0 )
    {
LABEL_36:
      if ( ((__int64)v26[0] & 1) == 0 )
        goto LABEL_37;
      goto LABEL_46;
    }
  }
  else if ( ((__int64)v27[0] & 1) == 0 )
  {
    goto LABEL_36;
  }
  operator delete(v27[2]);
  if ( ((__int64)v26[0] & 1) == 0 )
  {
LABEL_37:
    if ( ((__int64)v25[0] & 1) == 0 )
      goto LABEL_38;
    goto LABEL_47;
  }
LABEL_46:
  operator delete(v26[2]);
  if ( ((__int64)v25[0] & 1) == 0 )
  {
LABEL_38:
    if ( (v23 & 1) == 0 )
      goto LABEL_39;
    goto LABEL_48;
  }
LABEL_47:
  operator delete(v25[2]);
  if ( (v23 & 1) == 0 )
  {
LABEL_39:
    if ( ((__int64)v22[0] & 1) == 0 )
      goto LABEL_40;
    goto LABEL_49;
  }
LABEL_48:
  operator delete(*(void **)&v24[15]);
  if ( ((__int64)v22[0] & 1) == 0 )
  {
LABEL_40:
    if ( (v20 & 1) == 0 )
      goto LABEL_41;
LABEL_50:
    operator delete(*(void **)&v21[15]);
    if ( (v18 & 1) == 0 )
      return v15;
    goto LABEL_42;
  }
LABEL_49:
  operator delete(v22[2]);
  if ( (v20 & 1) != 0 )
    goto LABEL_50;
LABEL_41:
  if ( (v18 & 1) != 0 )
LABEL_42:
    operator delete(*(void **)&v19[15]);
  return v15;
}

check magisk and circumstance:

__int64 sub_151E0()
{
  size_t v0; // rax
  __int64 v1; // rax
  size_t v2; // rax
  size_t v3; // rax
  unsigned int v4; // ebx
  size_t v5; // rax
  const char *v6; // rax
  _OWORD v8[2]; // [rsp+0h] [rbp-10D8h] BYREF
  char s[4096]; // [rsp+20h] [rbp-10B8h] BYREF
  __int128 v10; // [rsp+1020h] [rbp-B8h]
  void *v11; // [rsp+1030h] [rbp-A8h]
  __int128 v12; // [rsp+1038h] [rbp-A0h]
  void *v13; // [rsp+1048h] [rbp-90h]
  __int128 v14; // [rsp+1050h] [rbp-88h]
  void *v15; // [rsp+1060h] [rbp-78h]
  char v16; // [rsp+1068h] [rbp-70h]
  char v17[9]; // [rsp+1069h] [rbp-6Fh] BYREF
  __int16 v18; // [rsp+1072h] [rbp-66h]
  int v19; // [rsp+1074h] [rbp-64h]
  void *v20; // [rsp+1078h] [rbp-60h]
  char v21; // [rsp+1080h] [rbp-58h]
  char v22[7]; // [rsp+1081h] [rbp-57h] BYREF
  __int64 v23; // [rsp+1088h] [rbp-50h]
  void *v24; // [rsp+1090h] [rbp-48h]
  char v25; // [rsp+1098h] [rbp-40h]
  char v26[23]; // [rsp+1099h] [rbp-3Fh] BYREF
  char v27; // [rsp+10B0h] [rbp-28h]
  char v28[11]; // [rsp+10B1h] [rbp-27h] BYREF
  int v29; // [rsp+10BCh] [rbp-1Ch]
  void *v30; // [rsp+10C0h] [rbp-18h]
  unsigned __int64 v31; // [rsp+10C8h] [rbp-10h]

  v31 = __readfsqword(0x28u);
  v10 = 0LL;
  v11 = 0LL;
  LOBYTE(v10) = 10;
  *(_DWORD *)((char *)&v10 + 1) = 0x7269722F;
  *(_WORD *)((char *)&v10 + 5) = 0x75;
  v12 = 0LL;
  v13 = 0LL;
  LOBYTE(v12) = 10;
  *(_DWORD *)((char *)&v12 + 1) = 1970432370;
  *(_WORD *)((char *)&v12 + 5) = 45;
  v14 = 0LL;
  v15 = 0LL;
  LOBYTE(v14) = 10;
  *(_WORD *)((char *)&v14 + 5) = 112;
  *(_DWORD *)((char *)&v14 + 1) = 2019845423;
  v17[8] = 0;
  v18 = 0;
  v19 = 0;
  v20 = 0LL;
  v16 = 14;
  strcpy(v17, "lsposed");
  v23 = 0LL;
  v24 = 0LL;
  v21 = 12;
  strcpy(v22, "magisk");
  *(_OWORD *)&v26[7] = 0LL;
  v25 = 12;
  strcpy(v26, "Magisk");
  v29 = 0;
  v30 = 0LL;
  v27 = 20;
  strcpy(v28, "/appwidget");
  if ( (unsigned __int8)sub_146E0("/proc/mounts") )
  {
    *(_QWORD *)&v8[1] = 0LL;
    LOBYTE(v8[0]) = 28;
    strcpy((char *)v8 + 1, "/proc/mounts->");
    v0 = strlen(s);
    v1 = sub_160D0(v8, s, v0);
  }
  else if ( (unsigned __int8)sub_146E0("/proc/self/mountstats") )
  {
    *(_QWORD *)&v8[1] = operator new(0x20uLL);
    v8[0] = xmmword_3B860;
    strcpy(*(char **)&v8[1], "/proc/self/mountstats->");
    v2 = strlen(s);
    v1 = sub_160D0(v8, s, v2);
  }
  else if ( (unsigned __int8)sub_146E0("/proc/self/mountinfo") )
  {
    strcpy((char *)v8, ",/proc/self/mountinfo->");
    v3 = strlen(s);
    v1 = sub_160D0(v8, s, v3);
  }
  else
  {
    v4 = 0;
    if ( !(unsigned __int8)sub_146E0("/proc/self/maps") )
      goto LABEL_15;
    BYTE1(v8[1]) = 62;
    WORD1(v8[1]) = 0;
    DWORD1(v8[1]) = 0;
    strcpy((char *)v8, "\"/proc/self/maps");
    v5 = strlen(s);
    v1 = sub_160D0(v8, s, v5);
  }
  if ( (*(_BYTE *)v1 & 1) != 0 )
    v6 = *(const char **)(v1 + 16);
  else
    v6 = (const char *)(v1 + 1);
  qword_4C040 = (__int64)strdup(v6);
  if ( (v8[0] & 1) != 0 )
    operator delete(*(void **)&v8[1]);
  v4 = 1;
LABEL_15:
  if ( (v27 & 1) != 0 )
  {
    operator delete(v30);
    if ( (v25 & 1) == 0 )
    {
LABEL_17:
      if ( (v21 & 1) == 0 )
        goto LABEL_18;
      goto LABEL_26;
    }
  }
  else if ( (v25 & 1) == 0 )
  {
    goto LABEL_17;
  }
  operator delete(*(void **)&v26[15]);
  if ( (v21 & 1) == 0 )
  {
LABEL_18:
    if ( (v16 & 1) == 0 )
      goto LABEL_19;
    goto LABEL_27;
  }
LABEL_26:
  operator delete(v24);
  if ( (v16 & 1) == 0 )
  {
LABEL_19:
    if ( (v14 & 1) == 0 )
      goto LABEL_20;
    goto LABEL_28;
  }
LABEL_27:
  operator delete(v20);
  if ( (v14 & 1) == 0 )
  {
LABEL_20:
    if ( (v12 & 1) == 0 )
      goto LABEL_21;
LABEL_29:
    operator delete(v13);
    if ( (v10 & 1) == 0 )
      return v4;
    goto LABEL_22;
  }
LABEL_28:
  operator delete(v15);
  if ( (v12 & 1) != 0 )
    goto LABEL_29;
LABEL_21:
  if ( (v10 & 1) != 0 )
LABEL_22:
    operator delete(v11);
  return v4;
}

check adb:

__int64 sub_157F0()
{
  char v0; // bl
  unsigned int v1; // ebp
  char *v2; // r13
  char *v3; // rbx
  char *v4; // rax
  char *v5; // rax
  char *v6; // rax
  char *v7; // rax
  char *v8; // rax
  const char *v9; // r14
  const char *v10; // r15
  char v11; // bp
  const char *v12; // r12
  const char *v13; // rsi
  const char *v14; // rsi
  const char *v15; // rsi
  const char *v16; // rsi
  const char *v17; // rsi
  const char *v18; // rsi
  char *v19; // r12
  size_t v20; // rbx
  const void *v21; // r14
  char *v22; // r15
  __int64 v23; // rax
  unsigned __int64 v24; // rdx
  unsigned __int64 v25; // rdx
  char *v26; // r12
  __int64 v27; // rax
  const char *v28; // rax
  void **v29; // rax
  void **v30; // rbx
  void *v31; // rdi
  char *v33; // [rsp+8h] [rbp-170h]
  char *v34; // [rsp+10h] [rbp-168h]
  char *v35; // [rsp+18h] [rbp-160h]
  char *v36; // [rsp+20h] [rbp-158h]
  char *haystack; // [rsp+28h] [rbp-150h]
  char v38; // [rsp+30h] [rbp-148h] BYREF
  char v39[11]; // [rsp+31h] [rbp-147h] BYREF
  int v40; // [rsp+3Ch] [rbp-13Ch]
  void *ptr; // [rsp+40h] [rbp-138h]
  __int128 dest[2]; // [rsp+50h] [rbp-128h] BYREF
  void *v43[2]; // [rsp+70h] [rbp-108h] BYREF
  __int64 v44; // [rsp+80h] [rbp-F8h]
  __int128 v45; // [rsp+90h] [rbp-E8h] BYREF
  void *v46; // [rsp+A0h] [rbp-D8h]
  __int128 v47; // [rsp+A8h] [rbp-D0h] BYREF
  void *v48; // [rsp+B8h] [rbp-C0h]
  __int128 v49; // [rsp+C0h] [rbp-B8h] BYREF
  void *v50; // [rsp+D0h] [rbp-A8h]
  char v51; // [rsp+D8h] [rbp-A0h] BYREF
  char v52[9]; // [rsp+D9h] [rbp-9Fh] BYREF
  __int16 v53; // [rsp+E2h] [rbp-96h]
  int v54; // [rsp+E4h] [rbp-94h]
  void *v55; // [rsp+E8h] [rbp-90h]
  char v56; // [rsp+F0h] [rbp-88h] BYREF
  char v57[7]; // [rsp+F1h] [rbp-87h] BYREF
  __int64 v58; // [rsp+F8h] [rbp-80h]
  void *v59; // [rsp+100h] [rbp-78h]
  char v60; // [rsp+108h] [rbp-70h] BYREF
  char v61[23]; // [rsp+109h] [rbp-6Fh] BYREF
  char v62[16]; // [rsp+120h] [rbp-58h] BYREF
  void *v63; // [rsp+130h] [rbp-48h]
  unsigned __int64 v64; // [rsp+140h] [rbp-38h]

  v64 = __readfsqword(0x28u);
  v45 = 0LL;
  v46 = 0LL;
  LOBYTE(v45) = 10;
  *(_DWORD *)((char *)&v45 + 1) = 1919513135;
  *(_WORD *)((char *)&v45 + 5) = 117;
  v47 = 0LL;
  v48 = 0LL;
  LOBYTE(v47) = 10;
  *(_DWORD *)((char *)&v47 + 1) = 1970432370;
  *(_WORD *)((char *)&v47 + 5) = 45;
  v49 = 0LL;
  v50 = 0LL;
  LOBYTE(v49) = 10;
  *(_WORD *)((char *)&v49 + 5) = 112;
  *(_DWORD *)((char *)&v49 + 1) = 2019845423;
  v52[8] = 0;
  v53 = 0;
  v54 = 0;
  v55 = 0LL;
  v51 = 14;
  strcpy(v52, "lsposed");
  v58 = 0LL;
  v59 = 0LL;
  v56 = 12;
  strcpy(v57, "magisk");
  *(_OWORD *)&v61[7] = 0LL;
  v60 = 12;
  strcpy(v61, "Magisk");
  *(_DWORD *)&v62[12] = 0;
  v63 = 0LL;
  v62[0] = 20;
  strcpy(&v62[1], "/appwidget");
  *(_OWORD *)v43 = 0LL;
  v44 = 0LL;
  strcpy((char *)&dest[1] + 1, "s/");
  DWORD1(dest[1]) = 0;
  strcpy((char *)dest, "$/data/adb/modul");
  v0 = 1;
  if ( !(unsigned __int8)sub_14840(dest, v43) )
  {
    v40 = 0;
    ptr = 0LL;
    v38 = 20;
    strcpy(v39, "/data/adb/");
    v0 = sub_14840(&v38, v43);
    if ( (v38 & 1) != 0 )
      operator delete(ptr);
  }
  if ( (dest[0] & 1) != 0 )
    operator delete(*(void **)&dest[1]);
  v1 = 0;
  if ( v0 )
  {
    v2 = (char *)v43[0];
    v3 = (char *)v43[1];
    if ( v43[0] == v43[1] )
    {
      v1 = 0;
      if ( !v43[0] )
        goto LABEL_86;
      goto LABEL_79;
    }
    if ( (v45 & 1) != 0 )
      v4 = (char *)v46;
    else
      v4 = (char *)&v45 + 1;
    haystack = v4;
    if ( (v47 & 1) != 0 )
      v5 = (char *)v48;
    else
      v5 = (char *)&v47 + 1;
    v36 = v5;
    if ( (v49 & 1) != 0 )
      v6 = (char *)v50;
    else
      v6 = (char *)&v49 + 1;
    v35 = v6;
    if ( (v51 & 1) != 0 )
      v7 = (char *)v55;
    else
      v7 = v52;
    v34 = v7;
    if ( (v56 & 1) != 0 )
      v8 = (char *)v59;
    else
      v8 = v57;
    v33 = v8;
    if ( (v60 & 1) != 0 )
    {
      v9 = *(const char **)&v61[15];
      if ( (v62[0] & 1) == 0 )
      {
LABEL_27:
        v10 = &v62[1];
        goto LABEL_30;
      }
    }
    else
    {
      v9 = v61;
      if ( (v62[0] & 1) == 0 )
        goto LABEL_27;
    }
    v10 = (const char *)v63;
    while ( 1 )
    {
LABEL_30:
      v11 = *v2;
      v12 = v2 + 1;
      v13 = v2 + 1;
      if ( (*v2 & 1) != 0 )
        v13 = (const char *)*((_QWORD *)v2 + 2);
      if ( strstr(haystack, v13) )
      {
        v19 = (char *)&v45;
        goto LABEL_60;
      }
      v14 = v2 + 1;
      if ( (v11 & 1) != 0 )
        v14 = (const char *)*((_QWORD *)v2 + 2);
      if ( strstr(v36, v14) )
      {
        v19 = (char *)&v47;
        goto LABEL_60;
      }
      v15 = v2 + 1;
      if ( (v11 & 1) != 0 )
        v15 = (const char *)*((_QWORD *)v2 + 2);
      if ( strstr(v35, v15) )
      {
        v19 = (char *)&v49;
        goto LABEL_60;
      }
      v16 = v2 + 1;
      if ( (v11 & 1) != 0 )
        v16 = (const char *)*((_QWORD *)v2 + 2);
      if ( strstr(v34, v16) )
      {
        v19 = &v51;
        goto LABEL_60;
      }
      v17 = v2 + 1;
      if ( (v11 & 1) != 0 )
        v17 = (const char *)*((_QWORD *)v2 + 2);
      if ( strstr(v33, v17) )
      {
        v19 = &v56;
        goto LABEL_60;
      }
      v18 = v2 + 1;
      if ( (v11 & 1) != 0 )
        v18 = (const char *)*((_QWORD *)v2 + 2);
      if ( strstr(v9, v18) )
      {
        v19 = &v60;
        goto LABEL_60;
      }
      if ( (v11 & 1) != 0 )
        v12 = (const char *)*((_QWORD *)v2 + 2);
      if ( strstr(v10, v12) )
        break;
      v2 += 24;
      if ( v3 == v2 )
      {
        v1 = 0;
        goto LABEL_78;
      }
    }
    v19 = v62;
LABEL_60:
    memset(dest, 0, 24);
    if ( (*v2 & 1) == 0 )
    {
      *(_QWORD *)&dest[1] = *((_QWORD *)v2 + 2);
      dest[0] = *(_OWORD *)v2;
LABEL_69:
      v23 = sub_160D0(dest, &unk_3BA97, 1LL);
      v24 = (unsigned __int8)*v19;
      if ( (v24 & 1) != 0 )
      {
        v25 = *((_QWORD *)v19 + 1);
        v26 = (char *)*((_QWORD *)v19 + 2);
      }
      else
      {
        v26 = v19 + 1;
        v25 = v24 >> 1;
      }
      v27 = sub_160D0(v23, v26, v25);
      if ( (*(_BYTE *)v27 & 1) != 0 )
        v28 = *(const char **)(v27 + 16);
      else
        v28 = (const char *)(v27 + 1);
      qword_4C040 = (__int64)strdup(v28);
      if ( (dest[0] & 1) != 0 )
        operator delete(*(void **)&dest[1]);
      v1 = 1;
      goto LABEL_78;
    }
    v20 = *((_QWORD *)v2 + 1);
    if ( v20 >= 0xFFFFFFFFFFFFFFF0LL )
      sub_14C10(dest);
    v21 = (const void *)*((_QWORD *)v2 + 2);
    if ( v20 >= 0x17 )
    {
      v22 = (char *)operator new((v20 + 16) & 0xFFFFFFFFFFFFFFF0LL);
      *(_QWORD *)&dest[1] = v22;
      *(_QWORD *)&dest[0] = (v20 + 16) & 0xFFFFFFFFFFFFFFF0LL | 1;
      *((_QWORD *)&dest[0] + 1) = v20;
    }
    else
    {
      LOBYTE(dest[0]) = 2 * v20;
      v22 = (char *)dest + 1;
      if ( !v20 )
        goto LABEL_68;
    }
    memcpy(v22, v21, v20);
LABEL_68:
    v22[v20] = 0;
    goto LABEL_69;
  }
LABEL_78:
  v2 = (char *)v43[0];
  if ( !v43[0] )
    goto LABEL_86;
LABEL_79:
  v29 = (void **)v43[1];
  if ( v43[1] == v2 )
  {
    v31 = v2;
  }
  else
  {
    do
    {
      v30 = v29 - 3;
      if ( (*(_BYTE *)(v29 - 3) & 1) != 0 )
        operator delete(*(v29 - 1));
      v29 = v30;
    }
    while ( v2 != (char *)v30 );
    v31 = v43[0];
  }
  v43[1] = v2;
  operator delete(v31);
LABEL_86:
  if ( (v62[0] & 1) != 0 )
  {
    operator delete(v63);
    if ( (v60 & 1) == 0 )
    {
LABEL_88:
      if ( (v56 & 1) == 0 )
        goto LABEL_89;
      goto LABEL_97;
    }
  }
  else if ( (v60 & 1) == 0 )
  {
    goto LABEL_88;
  }
  operator delete(*(void **)&v61[15]);
  if ( (v56 & 1) == 0 )
  {
LABEL_89:
    if ( (v51 & 1) == 0 )
      goto LABEL_90;
    goto LABEL_98;
  }
LABEL_97:
  operator delete(v59);
  if ( (v51 & 1) == 0 )
  {
LABEL_90:
    if ( (v49 & 1) == 0 )
      goto LABEL_91;
    goto LABEL_99;
  }
LABEL_98:
  operator delete(v55);
  if ( (v49 & 1) == 0 )
  {
LABEL_91:
    if ( (v47 & 1) == 0 )
      goto LABEL_92;
LABEL_100:
    operator delete(v48);
    if ( (v45 & 1) == 0 )
      return v1;
    goto LABEL_93;
  }
LABEL_99:
  operator delete(v50);
  if ( (v47 & 1) != 0 )
    goto LABEL_100;
LABEL_92:
  if ( (v45 & 1) != 0 )
LABEL_93:
    operator delete(v46);
  return v1;
}

代码很简单,留给读者自行分析了。

Android 端的 0 day 漏洞之一

该漏洞危害很大,直戳 反调试命脉 。不知道读者是否记得 io.eagle_sdk._init 函数?不记得没关系,我会把内容复制下来,方便阅读。

_init:

str soName = "eagle_sdk";
loadLibrary(soName);

这段代码有一个很大的问题,即 没有检查 handle 值是否正确,这个漏洞可直接被手动操作利用。

_fix_init:

str soName = "eagle_sdk";
int handle = loadLibrary(soName);
if  handle != 0 {
    // ... 请勿破解、程序异常
    // ... code
}

我们直接将 data/app/../lib 中的 eagle_sdk.so 删去,程序是可以正常运行的。此时,深造播放器 Android 便只有 java 层的反调试了,而 java 层的反调试(info0、1)早已被看的透透的了。。。

结尾

盗版网课 之所以泛滥仓绝,其中的重要原因便是 视频防止翻录 技术的极度落后。在这里推荐使用未来可能出现的 智多星视频加密 来保护 自己珍贵的网课!!!

中国最具影响力的视频加密公司  没有之一

合作伙伴:东北财经大学|  文都教育 | 苏州上普汽车 | 全通教育 | 新东方 | 万门大学 | 爱创课堂 | 成都希望卫校 | 学客之家 | 广州出国留学网 | 企业家出国培训 | 新思达